Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Draft
shivamhwp wants to merge 2 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Draft

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp wants to merge 2 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwp shivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability with activation lifecycle events and usage tracking across providers

  • Adds subagent_activation.updated event emission to all provider adapters (ACP, Claude, Codex, Cursor, OpenCode) so each activation has its own lifecycle record with status, timing, usage, and ordinal.
  • Introduces mergeCumulativeSubagentUsage and accumulateCumulativeSubagentUsage in SubagentObservability.ts to correctly compute lifetime token/tool-use totals across multiple activations without double-counting.
  • Adds appendSubagentActivity to track human-readable activity summaries on subagents, bounded to 6 entries with adjacent-duplicate deduplication.
  • Adds providerSubagentRole so provider-supplied role names are tagged with source: 'provider' rather than the app default.
  • Subagent status after completion is now 'idle' rather than 'completed'; currentActivationId is cleared on settlement and activationCount increments only on new activations.
  • The Claude adapter gains workflow coordinator/worker subagent projection from task_progress frames, including phases, membership, attempt tracking, and resumePending flag to correctly separate activations across wake-buffer replays.
  • Behavioral Change: new subagent tasks created by the Codex adapter now start in 'pending' status with activationCount: 0 instead of 'running' with activationCount: 1.
📊 Macroscope summarized 2565ea0. 9 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a90349b7-5ead-47ed-9033-d9e9fec92f6e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwp force-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2 Compare July 27, 2026 23:03
@shivamhwp
shivamhwp force-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111 Compare July 28, 2026 15:31
@shivamhwp
shivamhwp force-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9 Compare July 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mapping July 28, 2026 19:27
@shivamhwp
shivamhwp force-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0 Compare July 28, 2026 19:27
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwp force-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4a Compare July 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contracts July 28, 2026 20:12
shivamhwp and others added 2 commits July 29, 2026 01:52
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.

Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.

A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.

A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.

Three activation-lifecycle fixes in the Claude adapter, found in review:

- A resume that raced past settle was pre-opened by the wake buffer,
  which erased the terminal status the reopen check reads. The resume
  then reused the finished activation instead of starting a new one, so
  its ordinal stopped matching reality and its usage was measured
  against the previous activation's totals — clamping the delta to zero
  and silently dropping the resumed run's tokens. The pre-open now
  records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
  pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
  recorded completion time. Codex already preserved it; Claude now
  matches.

Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.

Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwp force-pushed the subagent-obs/02-adapters branch from bc22aac to 2567faf Compare July 28, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant